package dipl.algorithm.math.fp.primitive.op;

import dipl.algorithm.math.fp.primitive.Point2df;

/**
 * Class provides operations on points
 */
public class Point2dOps {

	//
	// PUBLIC METHODS
	//

	public static double Area( Point2df p0, Point2df p1, Point2df p2 ) {
		double a1 = p1.x-p0.x;
		double a2 = p2.y-p0.y;
		double a3 = p1.y-p0.y;
		double a4 = p2.x-p0.x;
		return a1*a2-a3*a4;
	}

	/**
	 * Tests whether given three points are collinear
	 * @param fpMath
	 * @param a
	 * @param b
	 * @param c
	 * @return
	 */
	public static boolean Collinear( Point2df a, Point2df b, Point2df c ) {
		double t1 = c.x*(a.y-b.y);
		double t2 = c.y*(b.x-a.x);
		double t3 = a.x*b.y;
		double t4 = a.y*b.x;
		double res = t1+t2+t3-t4;
		return (res == 0.0);
	}

	/**
	 * Compares given two points lexicographically.
	 * first x-coordinates are compared and if both are equal the y-coordinates are compared.
	 * @param a
	 * @param b
	 * @return
	 */
	public static int ComparePointsLexicographically( Point2df a, Point2df b ) {
		if( a.x != b.x ) return (a.x < b.x ? -1 : 1);
		if( a.y != b.y ) return (a.y < b.y ? -1 : 1);
		return 0;
	}

	/**
	 * Compares given two points lexicographically.
	 * first x-coordinates are compared and if both are equal the y-coordinates are compared.
	 * @param ax
	 * @param ay
	 * @param bx
	 * @param by
	 * @return
	 */
	public static int ComparePointsLexicographically( double ax, double ay, double bx, double by ) {
		if( ax != bx ) return (ax < bx ? -1 : 1);
		if( ay != by ) return (ay < by ? -1 : 1);
		return 0;
	}

	/**
	 * Returns of distance from a to b
	 * @param a
	 * @param b
	 * @return
	 */
	public static double Distance( Point2df a, Point2df b ) {
		double x = a.x-b.x;
		double y = a.y-b.y;
		return Math.sqrt( x*x+y*y );
	}

	/**
	 * Calculates dot product of vectors pointing to given two points
	 * @param fpMath
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static double DotProduct( Point2df p1, Point2df p2 ) {
		return p1.x*p2.x+p1.y*p2.y;
	}

	/**
	 * Tests whether or not lines (p1,p0) and (p2,p1) make a left turn at p1.
	 * @param fpMath
	 * @param p0
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static boolean MakeLeftTurn( Point2df p0, Point2df p1, Point2df p2 ) {
		return Area( p0, p1, p2 ) > 0.0;
	}

	/**
	 * Tests whether or not lines (p1,p0) and (p2,p1) make a right turn at p1.
	 * @param fpMath
	 * @param p0
	 * @param p1
	 * @param p2
	 * @return
	 */
	public static boolean MakeRightTurn( Point2df p0, Point2df p1, Point2df p2 ) {
		return Area( p0, p1, p2 ) < 0.0;
	}

	/**
	 * Returns square of distance from a to b
	 * @param a
	 * @param b
	 * @return
	 */
	public static double SquareDistance( Point2df a, Point2df b ) {
		double x = a.x-b.x;
		double y = a.y-b.y;
		return x*x+y*y;
	}
}
